﻿// ע�



using InfluxDB.Client.Api.Domain;
using IotClientService;
using IotClientService.Managers;
using IotClientService.Services;
using IotContract.Interfaces;
using IotContract.Interfaces.Fmt;
using IotContract.Interfaces.Process;
using IotServerService.Services;
using IotServerService.Services.Datas;
using IotServerService.Services.Datas.Managers;
using IotServerService.Services.Mqtts;
using IotServerService.Services.Remotes;

using Microsoft.Extensions.DependencyInjection;

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using XT.Common;
using XT.Sql;
using XT.Sql.Extensions;

namespace IotServerService;
public static class Register
{
    /// <summary>
    /// 注册单例服务
    /// </summary>
    /// <param name="services"></param>
    /// <returns></returns>
    public static object RegisterServerService(this IServiceCollection services)
    {


        // 添加Sql
        services.AddXTDbSetup();

        XTDbContext.AopSqlEvent += (o, e) =>
        {

        };

        // 添加Db数据库服务
        services.AddSingleton<DbService>();
        // 添加http服务
        services.AddOriginHttpClient();

        // connect连接数据服务
        services.AddSingleton<IConnectDataService,ConnectDataService>();
        // mqtt连接服务端管理
        //services.AddSingleton<IMqttManager, MqttManager>();
        //添加Mqtt服务
        services.AddSingleton<IMqttServerService, MqttServerService>();
        // remote远程调用服务
        //services.AddSingleton<IRemoteHttpService, RemoteHttpService>();
        // 通用api服务
        services.AddSingleton<IProcessApiHandle, ProcessMockApiHandleService>();

        // 添加数据管理入口
        services.AddSingleton<IServerMainManager, ServerMainManager>(); 
        
        // 添加设备数据管理，根据协议区分
        var handles = typeof(SiemensS7DataManager).Assembly.GetTypes().Where(x => x.IsClass && !x.IsAbstract && x.GetInterface(nameof(IServerDataManager)) != null);
        foreach (var handle in handles)
        {
            services.AddSingleton(typeof(IServerDataManager), handle);
        }

       
       
        // 注册客户端服务
        services.RegisterClientService();
        return services;
    }
    /// <summary>
    /// 注册扩展处理程序
    /// </summary>
    /// <param name="services"></param>
    /// <returns></returns>
    public static IServiceCollection RegisterServerProcess(this IServiceCollection services)
    {
        string url = AppDomain.CurrentDomain.BaseDirectory + "ProcessExtensions";
        if (!Directory.Exists(url))
        {
            return services;
        }
        var files = Directory.GetFiles(url);
       var dlls= files.Where(x => x.EndsWith(".dll"));
        if(!dlls.Any()) 
        {
            return services;
        }
        foreach(var dll in dlls)
        {
           var types= Assembly.LoadFrom(dll).GetExportedTypes();


           // 设备调度
            var handles=types.Where(x=>x.IsClass && !x.IsAbstract && x.GetInterface(nameof(IServerProcessHandle))!=null);
            foreach(var handle in handles)
            {
                services.AddSingleton(typeof(IServerProcessHandle), handle);
            }
            //开放数据
           var processOpen = types.FirstOrDefault(x => x.IsClass && !x.IsAbstract && x.GetInterface(nameof(IProcessOpenProvider)) != null);

            if (processOpen != null)
            {
                services.AddSingleton(typeof(IProcessOpenProvider), processOpen);
            }
            // 调度入口
            var imple= types.FirstOrDefault(x => x.IsClass && !x.IsAbstract && x.GetInterface(nameof(IServerMainProcess)) != null);
            services.AddSingleton(typeof(IServerMainProcess), imple);

            var injects = types.Where(x => x.IsClass && !x.IsAbstract && x.Name.EndsWith("Service", StringComparison.OrdinalIgnoreCase));
            foreach(var inject in injects)
            {
                var inter = inject.GetInterface("I" + inject.Name);
                if (inter != null)
                {
                    services.AddSingleton(inter, inject);
                }
            }
          
        }


        return services;

    }
}
